// prettier配置
const prettier = require('prettier');
const styleOrder = require('prettier-plugin-style-order');
const express = require('express');
const bodyParser = require('body-parser');
const compression = require('compression');
const { ESLint } = require('eslint');

const app = express();
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true, parameterLimit: 50000 }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.text());
app.use(bodyParser.raw());
app.use(compression());

// CodeFormat服务入口
app.post('/codeFormat', async (req, res) => {
  try {
    const params = {
      ...req.body
    };
    // 使用prettier格式化html+js+css代码
    const sourceCode = params.sourceCode;
    // 获取解析器类型
    const parserType = params.parserType;
    // prettier规则
    const options = {
      printWidth: 10000, // 单行最大长度
      tabWidth: 2, // tab缩进大小,默认为2
      parser: parserType, // 解析器
      htmlWhitespaceSensitivity: 'ignore', // 空格敏感模式
      semi: true, // 总是在语句末尾打印分号
      bracketSpacing: true, // 对象中打印空格 例如：true: {foo: bar} => true: { foo: bar }
      singleQuote: true, // 字符串使用单引号
      jsxBracketSameLine: true, // 标签尖括号放在行末，而不是下一行(对自闭元素不生效)
      arrowParens: 'always', // 在单个箭头函数参数周围加上括号
      plugins: [styleOrder], // 引入排序的插件
      styleOrder: {
        alphabetize: true // 对css样式的属性按照字母进行排序
      }
    };
    // 使用prettier格式化代码
    params.sourceCode = await prettier.format(sourceCode, options);
    const messages = [];
    let isSucceed = true;
    // 是否存在错误
    try {
      const eslint = new ESLint();
      const results = await eslint.lintText(params.sourceCode);
      results.forEach((result) => {
        if (result.fatalErrorCount > 0) {
          result.messages.forEach((message) => {
            if (message.fatal) {
              const msg = {
                msg: message.message,
                line: message.line,
                column: message.column
              };
              messages.push(msg);
            }
          });
        }
      });
      if (messages.length > 0) {
        isSucceed = false;
      }
    } catch (e) {
      console.error('格式化校验失败', e);
    }
    // 生成返回对象
    const prettierResult = {
      data: {
        output: params.sourceCode,
        messages: messages,
        isSucceed: isSucceed
      }
    };
    res.json(prettierResult);
  } catch (error) {
    console.error(`格式化失败`, error);
  }
});

function main() {
  // 解析命令行的端口号
  const port = process.argv[2].split('=')[1];
  // 启动服务
  app.listen(port, () => {
    console.info(`prettier server listening at http://localhost:${port}`);
  });
}

main();
